home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / utilities / findhit4.lha / FindHit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-01  |  8.1 KB  |  398 lines

  1. /*
  2. ** $VER: FindHit 37.4 (1.7.93)
  3. **
  4. ** Finds the C source line of an Enforcer or Mungwall Hit, given the Slink
  5. ** mapfile and object files compiled with at least DEBUG=LINE.
  6. **
  7. ** Written by Douglas Keller
  8. **
  9. */
  10.  
  11. #include "headers.h"
  12.  
  13. #define VERSION "37.4 (1.7.93)"
  14.  
  15. struct GlobalData {
  16.     struct Library *SysBase;
  17.     struct Library *DOSBase;
  18.  
  19.     ULONG hunk;
  20.     BOOL delete_omdfile;
  21.  
  22.     UBYTE omdfile[44];    /* keep the mapfilename to delete if delete_omdfile is TRUE */
  23.     
  24.     UBYTE buffer[512];
  25. };
  26. typedef struct GlobalData GLOB;
  27.  
  28. static const UBYTE *ver= "$VER: FindHit " VERSION "";
  29.  
  30. /***** prototypes *****/
  31. static LONG find_hit_from_map(GLOB *z, UBYTE *mapfile, UBYTE *offset);
  32. static void find_filename_and_base_column(UBYTE *buffer, UWORD *ofile_column, UWORD *base_column);
  33. static LONG find_offset_from_omd(GLOB *z, UBYTE *ofile, UBYTE *cfile, ULONG base, ULONG hit_offset);
  34. static BOOL diff_time(GLOB *z, UBYTE *file1, UBYTE *file2);
  35. static LONG keyOfFile(GLOB *z, UBYTE *str);
  36. static LONG hexToLong(UBYTE *str);
  37. static void SPrintf(struct Library *SysBase, STRPTR buffer, STRPTR format, ...);
  38.  
  39. #define TEMPLATE "MAPFILE/A,OFFSET/A/M,HUNK/N,DEL=DELETEOMDFILE/S"
  40. #define OPT_MAPFILE        0
  41. #define OPT_OFFSET        1
  42. #define OPT_HUNK        2
  43. #define OPT_DELETE        3
  44. #define OPT_COUNT        4
  45. LONG StartUpCode(void)
  46. {
  47.   GLOB *z;
  48.   struct Library *SysBase=*((void **)4L);
  49.   struct RDArgs *rdargs;
  50.   UBYTE **str;
  51.   LONG opts[OPT_COUNT];
  52.   LONG retval=RETURN_FAIL;
  53.  
  54.  
  55.     if( z=AllocMem(sizeof(GLOB),MEMF_ANY) )
  56.         {
  57.         z->SysBase= SysBase;
  58. #define DOSBase z->DOSBase
  59. #define SysBase z->SysBase
  60.         if( DOSBase=OpenLibrary("dos.library", 37L) )
  61.             {
  62.             memset(opts, 0, sizeof(opts));
  63.             if( rdargs=ReadArgs(TEMPLATE, opts, NULL) )
  64.                 {
  65.                 
  66.                 if( opts[OPT_HUNK] )
  67.                     {
  68.                     z->hunk= *((LONG *)opts[OPT_HUNK]);
  69.                     }
  70.                 else
  71.                     {
  72.                     z->hunk= 0;
  73.                     }
  74.                 if( opts[OPT_DELETE] )
  75.                     {
  76.                     z->delete_omdfile=TRUE;
  77.                     }
  78.                 else
  79.                     {
  80.                     z->delete_omdfile=FALSE;
  81.                     }
  82.  
  83.                 Printf("\2331m_FindHit_\2330m " VERSION " by Douglas Keller\n\n");
  84.  
  85.                 str= (UBYTE **) opts[OPT_OFFSET];
  86.                 while( *str )
  87.                     {
  88.                     if( retval= find_hit_from_map(z, (UBYTE *)opts[OPT_MAPFILE], *str) )
  89.                         {
  90.                         break;
  91.                         }
  92.                     str++;
  93.                     }
  94.  
  95.                 if( z->delete_omdfile ) DeleteFile(z->omdfile);
  96.  
  97.                 Printf("\n");
  98.                 
  99.                 FreeArgs(rdargs);
  100.                 }
  101.             else
  102.                 {
  103.                 PrintFault(IoErr(), NULL);
  104.                 }
  105.  
  106.             CloseLibrary(DOSBase);
  107.             }
  108.         FreeMem(z, sizeof(GLOB));
  109.         }
  110.     return( retval );
  111. }
  112.  
  113. static LONG find_hit_from_map(GLOB *z, UBYTE *mapfile, UBYTE *offset_str)
  114. {
  115.   BPTR fh;
  116.   BPTR lock, old_cd, exists;
  117.   UBYTE *buffer= z->buffer;
  118.   UBYTE *ptr, cfile[256], ofile[256], *lastchar, *cfile_ptr;
  119.   BOOL start=FALSE;
  120.   BOOL hunkfound=FALSE;
  121.   ULONG hit_offset;
  122.   ULONG offset, lastoffset=0;
  123.   LONG retval=RETURN_FAIL;
  124.   UBYTE path[256];
  125.   UWORD ofile_column, base_column;
  126.  
  127.  
  128.     hit_offset= hexToLong(offset_str);
  129.     strcpy(path, mapfile);
  130.     *(PathPart(path))= NULL;
  131.     if( lock=Lock(path,SHARED_LOCK) )  /* CD to mapfile dir, so we can find #?.(c|o) files */
  132.         {
  133.         old_cd= CurrentDir(lock);
  134.         }
  135.  
  136.     if( fh=Open(FilePart(mapfile), MODE_OLDFILE) )
  137.         {
  138.         SetVBuf(fh, NULL, BUF_FULL, 4096);
  139.         while( FGets(fh, buffer, 512) )
  140.             {
  141.             if( !start && buffer[0]==' '&&buffer[1]=='n'&&buffer[2]=='u'&&buffer[3]=='m' )
  142.                 {
  143.                 find_filename_and_base_column(buffer, &ofile_column, &base_column);
  144.                 start=TRUE;
  145.                 continue;
  146.                 }
  147.             else if( start && buffer[0]==0x0c )
  148.                 {
  149.                 start=FALSE;
  150.                 continue;
  151.                 }
  152.  
  153.             if( start && !hunkfound )
  154.                 {
  155.                 if( buffer[3] != ' ' )
  156.                     {
  157.                     buffer[4]= NULL;
  158.                     if( z->hunk == hexToLong(buffer) )
  159.                         {
  160.                         hunkfound=TRUE;
  161.                         }
  162.                     }
  163.                 }
  164.             if( start && hunkfound )
  165.                 {
  166.                 /* find .o name and base */
  167.                 ptr= buffer + ofile_column;
  168.                 while( *++ptr != ' ' )
  169.                     {
  170.                     }
  171.                 *ptr=
  172.                 buffer[base_column + 8]= NULL;
  173.                 ptr= buffer + ofile_column;
  174.                 offset= hexToLong(buffer+base_column);
  175.  
  176.                 if( offset > hit_offset )
  177.                     {
  178.                     cfile_ptr= cfile;
  179.                     if( exists=Lock(cfile, SHARED_LOCK) )
  180.                         {
  181.                         UnLock(exists);
  182.                         }
  183.                     else
  184.                         {
  185.                         if( old_cd ) CurrentDir(old_cd);
  186.                         if( exists=Lock(FilePart(cfile), SHARED_LOCK) )
  187.                             {
  188.                             cfile_ptr= FilePart(cfile);
  189.                             strcpy(ofile, cfile_ptr);
  190.                             lastchar= ofile + strlen(ofile)-1;
  191.                             if( *lastchar == 'c' ) *lastchar='o';
  192.                             UnLock(exists);
  193.                             }
  194.                         }
  195.                     Printf("Found offset 0x%08lx in \"%s\", ", hit_offset, cfile_ptr);
  196.                     Flush(Output());
  197.  
  198.                     retval= find_offset_from_omd(z, ofile, cfile_ptr, lastoffset, hit_offset);
  199.  
  200.                     break;
  201.                     }
  202.  
  203.                 strcpy(ofile, ptr);
  204.                 strcpy(cfile, ptr);
  205.                 lastchar= cfile + strlen(cfile)-1;
  206.                 if( *lastchar == 'o' ) *lastchar='c';
  207.                 lastoffset= offset;
  208.                 }
  209.  
  210.             }
  211.         Close(fh);        
  212.         }
  213.     else
  214.         {
  215.         Printf("Error: could not open mapfile '%s'\n", mapfile);
  216.         }
  217.  
  218.     if( lock )
  219.         {
  220.         CurrentDir(old_cd);
  221.         UnLock(lock);
  222.         }
  223.  
  224.     return( retval );
  225. }
  226.  
  227. static void find_filename_and_base_column(UBYTE *buffer, UWORD *ofile_column, UWORD *base_column)
  228. {
  229.   UBYTE *ptr = buffer;
  230.  
  231.     /* find column of "filename", it is guaranteed to be the first 'f' */
  232.     while( *ptr++ )
  233.         {
  234.         if( *ptr == 'f' )
  235.             {
  236.             *ofile_column = ptr - buffer;
  237.             break;
  238.             }
  239.         }
  240.     /* find column of "base", it is guaranteed to be the first 'b' */
  241.     while( *ptr++ )
  242.         {
  243.         if( *ptr == 'b' )
  244.             {
  245.             *base_column = ptr - buffer - 4; /* -4 since the largest number is 8 chars */
  246.             break;
  247.             }
  248.         }
  249. }
  250.  
  251. #define SEMICOLON 1
  252. #define VERTBAR   2
  253.  
  254. static LONG find_offset_from_omd(GLOB *z, UBYTE *ofile, UBYTE *cfile, ULONG base, ULONG hit_offset)
  255. {
  256.   BPTR clock, olock;
  257.   BPTR fh;
  258.   ULONG line_num=0,found_line=0;
  259.   ULONG offset;
  260.   UBYTE *buffer= z->buffer;
  261.   UWORD last=0;
  262.   UBYTE *omdfile=z->omdfile;
  263.   LONG retval=RETURN_FAIL;
  264.   LONG system_retval=0;
  265.  
  266.     if( clock=Lock(cfile, SHARED_LOCK) )
  267.         {
  268.         if( olock=Lock(ofile, SHARED_LOCK) )
  269.             {
  270.             SPrintf(SysBase, omdfile, "t:fh%lx_%s", keyOfFile(z,cfile), FilePart(cfile));
  271.             strcpy(omdfile+strlen(omdfile)-1, "omd");
  272.  
  273.             if( diff_time(z, ofile, omdfile) )
  274.                 {
  275.                 SPrintf(SysBase, buffer, "omd \"%s\" \"%s\" >%s", ofile, cfile, omdfile);
  276.                 system_retval=SystemTags(buffer,
  277.                                     SYS_UserShell, TRUE,
  278.                                     TAG_DONE);
  279.                 if( system_retval )
  280.                     {
  281.                     DeleteFile(omdfile);
  282.                     Printf("Error: error running OMD.\n");
  283.                     }
  284.                 }
  285.  
  286.             if( system_retval==0 && (fh=Open(omdfile, MODE_OLDFILE)) )
  287.                 {
  288.                 SetVBuf(fh, NULL, BUF_FULL, 4096);
  289.                 retval= RETURN_WARN;
  290.  
  291.                 while( FGets(fh, buffer, 100) )
  292.                     {
  293.                     if( buffer[0] == ';' )
  294.                         {
  295.                         line_num++;
  296.                         last= SEMICOLON;
  297.                         }
  298.                     if( buffer[7] == '|' )
  299.                         {
  300.                         buffer[13]= NULL;
  301.                         offset= hexToLong(buffer+9);
  302.  
  303.                         if( base + offset >= hit_offset )
  304.                             {
  305.                             Printf("on line %ld\n", found_line);
  306.                             retval=RETURN_OK;
  307.                             break;
  308.                             }
  309.  
  310.                         if( last == SEMICOLON ) found_line= line_num;
  311.                         last= VERTBAR;
  312.                         }
  313.                     }
  314.  
  315.                 if( retval != RETURN_OK ) Printf("line number not found.\n");
  316.  
  317.                 Close(fh);
  318.                 }
  319.  
  320.             UnLock(olock);
  321.             }
  322.         else
  323.             {
  324.             Printf("Error: could not open \"%s\".\n", ofile);
  325.             }
  326.         UnLock(clock);
  327.         }
  328.     else
  329.         {
  330.         Printf("Error: could not open \"%s\".\n", cfile);
  331.         }
  332.     return( retval );
  333. }
  334.  
  335. static BOOL diff_time(GLOB *z, UBYTE *file1, UBYTE *file2)
  336. {
  337.   BPTR lock1;
  338.   BPTR lock2;
  339.   struct FileInfoBlock __aligned fib1;
  340.   struct FileInfoBlock __aligned fib2;
  341.   BOOL retval=TRUE;
  342.  
  343.     if( lock1=Lock(file1,SHARED_LOCK) )
  344.         {
  345.         if( lock2=Lock(file2,SHARED_LOCK) )
  346.             {
  347.             if( Examine(lock1,&fib1) && Examine(lock2,&fib2) )
  348.                 {
  349.                 if( 0 <= CompareDates(&fib1.fib_Date, &fib2.fib_Date) )
  350.                     {
  351.                     retval=FALSE;
  352.                     }
  353.                 }
  354.             UnLock(lock2);
  355.             }
  356.         UnLock(lock1);
  357.         }
  358.     return( retval );
  359. }
  360.  
  361. static LONG hexToLong(UBYTE *str)
  362. {
  363.   LONG num;
  364.  
  365.     while( *str == ' ' )
  366.         {
  367.         str++;
  368.         }
  369.  
  370.     stch_l(str, &num);
  371.     return( num );
  372. }
  373.  
  374. static LONG keyOfFile(GLOB *z, UBYTE *str)
  375. {
  376.   BPTR lock;
  377.   struct FileInfoBlock __aligned fib;
  378.   LONG key=0;
  379.  
  380.     if( lock=Lock(str, SHARED_LOCK) )
  381.         {
  382.         if( Examine(lock, &fib) )
  383.             {
  384.             key= fib.fib_DiskKey; /* key will be unique even if filenames are the same */
  385.             }
  386.         UnLock(lock);
  387.         }
  388.     return( key );
  389. }
  390.  
  391. #undef SysBase
  392. static void SPrintf(struct Library *SysBase, STRPTR buffer, STRPTR format, ...)
  393. {
  394.  
  395.     RawDoFmt( format, (APTR)(&format+1), (void (*))"\x16\xc0\x4e\x75", buffer);
  396. }
  397.  
  398.